/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "时间轴.h"
#include "A_引擎/文件工程/工程文件.h"

using namespace std;

static uint16	g时间轴属性ID = 0;
static uint16	g文本刻度属性ID = 0;
static bool		g开始移动视口 = false;
static bool		g开始移动帧 = false;
//static float32	g时间间隔绘制比例 = 50.0f;

std::set<C_时间轴*> C_时间轴::g_当前时间轴页面;



DEF_单色绘制ID(时间轴背景)
DEF_单色绘制ID(时间线)
DEF_文本绘制ID(刻度)




Inline static void f_update时间线绘制(C_Widget* self, C_时间轴* view) {
	auto* f = f_projectFile_取当前工程文件();
	auto frame = f_NodeCtx_get帧();
	return;

}


static bool f_时间轴页面鼠标点击(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);
	
	f_时间工作区_从鼠标位置计算时间帧(self);
	
	f_时间轴_更新状态栏(true);
	
	f_时间工作区_刷新时间线绘制(view, view->m_时间线绘制, f_prop_I32(f_NodeCtx_get帧().当前帧), self->m_父部件->m_Size.y);
	
	//f_时间工作区_时间线绘制(view, view->m_时间线绘制);
	f_页面_更新联动工作区(E_工作区类型::e_时间轴);
	f_node_帧更新(true);

	return true;
}

static bool f_时间轴页面鼠标按下(C_Widget* self, const E_鼠标按钮& 按钮) {

	if (按钮 == E_鼠标按钮::e_鼠标左键) {
		g开始移动帧 = true;
	} else if (按钮 == E_鼠标按钮::e_鼠标中键) {
		g开始移动视口 = true;
	}

	return true;
}

static bool f_时间轴页面鼠标放开(C_Widget* self, const E_鼠标按钮& 按钮) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);

	if (按钮 == E_鼠标按钮::e_鼠标左键) {
		f_update时间线绘制(self, view);
	} else if (按钮 == E_鼠标按钮::e_鼠标中键) {
		g开始移动视口 = false;
	}

	g开始移动帧 = false;

	return true;
}

static bool f_时间轴页面鼠标位置改变(C_Widget* self, const ivec4& mouse) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);


	vec2 globalLoc{ float32(mouse.x), float32(mouse.y)};
	static vec2 absLoc = globalLoc;
	if (g开始移动视口) {
		C_Widget* view = f_ui_get滚动框视口(self);

		absLoc = globalLoc - absLoc;

		self->m_扩展视口属性->m_中心.x += absLoc.x;
		self->m_扩展视口属性->m_中心.y += absLoc.y;
		//self->m_Size.x += absLoc.x;
		//self->m_Size.y += absLoc.y;

		f_Widget_应用视口移动(self, view);
	}

	/*if (g开始移动帧) {
		auto* f = f_projectFile_取当前工程文件();

		auto c = f_widget_get鼠标局部位置(self->g_鼠标.gPos, view);
		int64 当前帧 = f_widget_转换坐标到原始坐标(c - self->m_扩展视口属性->m_中心.x, view).x;
	
		//cout << "当前帧 = " << 当前帧 / view->m_帧步进宽度 << " " << 当前帧 << " " << view->m_帧步进宽度 << " " << view->m_帧数字步进 << endl;
		f_NodeCtx_set场景当前时间(((当前帧) / (view->m_帧步进宽度 * 2 / view->m_帧数字步进)) + 0.5);
		//cout << "当前帧 = " << f_prop_I32(f->m_当前帧) << endl;
		view->f_刷新时间帧绘制();
		//f->m_当前帧.m_UI->m_Set(f->m_当前帧);
		f_时间轴_帧绘制更新(true);

		f_node_帧更新(true);
		//f_node_Step节点数(f_prop_I32(f->m_当前帧));
		f_node_Step节点数(1);
		f_node_帧更新(false);
	}*/

	f_update时间线绘制(self, view);

	absLoc = globalLoc;

	return true;
}









void f_时间轴动画(C_Widget* self) {
	//if (g时间更新绘制更新) {
	//	C_时间轴* view = dynamic_cast<C_时间轴*>(f_ui_get滚动框视口(self));
		//f_update时间线绘制(self, view);
	//}
}






static void f_时间轴布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);

	f_Widget_计算视口缩放保持偏移比例(self);
}


static void f_draw时间轴(C_Widget* self, S_2D画布* 画布) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);

	g时间轴属性ID = f_vg_gen属性(画布);
	g文本刻度属性ID = f_vg_gen属性(画布);

	
	S_凸边图元 图元 = {};
	图元.属性 = f_vg_get属性指针(画布, g时间轴属性ID);
	view->m_背景绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);
	
	//绘制刻度线
	view->m_DT刻度线.f_Draw(画布, g文本刻度属性ID);
	
	const auto& 字体 = f_surface_get字体库(*self->m_UIctx, S_UI主题::ui_默认字体);
	view->m_标签绘制.f_Draw(画布, &字体, g文本刻度属性ID);

	
	//时间线绘制
	图元 = {};
	图元.属性 = f_vg_get属性指针(画布, g时间轴属性ID);
	view->m_时间线绘制.f_Draw(画布, 图元, E_笔刷类型::e_单色描边);

	self->m_画布->m_是否重绘 = true;
}

static void f_set时间轴变换(C_Widget* self) {
	C_时间轴* view = dynamic_cast<C_时间轴*>(self);

	auto* f = f_projectFile_取当前工程文件();

	int32 方向 = E_方向::e_纵向;

	S_2D顶点属性 属性 = { {1,1}, {0,0}, 1, 方向 };
	属性.m_偏移 = {};
	属性.m_间隔 = 0;
	f_vg_set属性(self->m_画布, g时间轴属性ID, 属性);

	S_2D顶点属性 文本属性 = {};
	文本属性.m_比例 = {1,1};
	文本属性.m_偏移 = { self->m_扩展视口属性->m_中心.x, 0 };
	文本属性.m_渐变数量 = 方向;
	文本属性.m_间隔 = 2;
	f_vg_set属性(self->m_画布, g文本刻度属性ID, 文本属性);


	
	view->m_背景绘制.f_alloc(2);
	mat3X2 mat;
	mat.row0 = {};
	mat.row1 = self->m_Size;
	mat.row2 = { 1, 0 };
	view->m_背景绘制.f_set单色填充(0, mat, S_主题颜色::uic_时间轴背景, S_Widget预设图元::m_矩形);

	
	
	//时间区背景
	mat = f_时间工作区_时间区间绘制矩阵(self);
	mat.row1.y = self->m_Size.y;
	view->m_背景绘制.f_set单色填充(1, mat, S_主题颜色::uic_时间轴时间区, S_Widget预设图元::m_矩形);
	
	
	//return;
	vec2 帧绘制间隔宽度 = mat.row1;
	vec2 刻度线步进宽度 = { 帧绘制间隔宽度.x, 1 };
	//线数量 = (mat.row1.x * self->m_扩展视口属性->m_比例.x);

	auto& time = f_prop_iVec2(f_NodeCtx_get帧().帧区间);
	
	刻度线步进宽度.x = f_时间工作区_计算尺线绘制间隔(刻度线步进宽度.x);
	view->m_帧步进宽度 = (mat.row1.x / ((view->m_线数量+1) * 2));
	

	//return;
	view->m_DT刻度线.f_alloc(1);
	mat.row0 = {};
	mat.row1.x = 1;
	mat.row1.y = self->m_Size.y;
	mat.row2 = 刻度线步进宽度;
	//g_DT刻度线.f_set((time.y - time.x), mat, S_节点UI主题::uic_刻度线L1, S_UI主题::uic_文字颜色);
	view->m_DT刻度线.f_set((time.y - time.x), mat, S_节点UI主题::uic_刻度线L1);
	

	//return;
	vec2 数量步进 = f_时间工作区_计算刻度文本_数量步进(帧绘制间隔宽度.x, 刻度线步进宽度.x);
	view->m_标签绘制.f_alloc(数量步进.x, 12);
	view->m_标签绘制.f_绘制刻度数字(S_Rect2Df{ {0.0f,0.0f}, {60.0f,10.0f} }, int32(数量步进.x), { 0, 数量步进.y }, 刻度线步进宽度.x * 2);


	
	//f_时间工作区_刷新时间线绘制(view, view->m_时间线绘制, f_prop_I32(f_NodeCtx_get帧().当前帧), self->m_父部件->m_Size.y);
	f_时间工作区_时间线绘制(view, view->m_时间线绘制);

	return;
}


C_时间轴::C_时间轴(S_UI创建环境& ctx) : C_Widget(&ctx) {
	mf_布局Fun	= f_时间轴布局;
	mf_DrawFun	= f_draw时间轴;
	mf_变换修改	= f_set时间轴变换;


	mf_鼠标按键点击 = f_时间轴页面鼠标点击;
	mf_鼠标按键按下 = f_时间轴页面鼠标按下;
	mf_鼠标按键放开 = f_时间轴页面鼠标放开;
	mf_鼠标移动 = f_时间轴页面鼠标位置改变;
	//mf_鼠标滚轮 = f_时间轴页面鼠标滚轮;

	f_setSize({ 256, 256 });
	m_线数量 = 1;
	m_帧数字步进 = 1;
	m_帧步进宽度 = 1;


	C_时间轴::g_当前时间轴页面.insert(this);
}

C_时间轴::~C_时间轴() {
	C_时间轴::g_当前时间轴页面.erase(this);
}

void C_时间轴::f_刷新时间帧绘制() {
	if (m_父部件) {
		f_时间工作区_刷新时间线绘制(this, m_时间线绘制, f_prop_I32(f_NodeCtx_get帧().当前帧), m_父部件->m_Size.y);
		//f_时间工作区_时间线绘制(this, m_时间线绘制);
	}
	
}












C_Widget* f_创建时间轴页面(S_UI创建环境& ctx) {
	C_时间轴* 时间轴 = new C_时间轴(ctx);
	f_widget_开启视口属性(时间轴);
	时间轴->m_扩展视口属性->m_大小 = { 1024, 256 };

	auto* 滚动窗口 = f_ui_创建滚动框(ctx, true, false, 时间轴);
	//滚动窗口->mf_鼠标滚轮 = f_时间轴页面鼠标滚轮;
	//滚动窗口->mf_布局Fun	= f_时间轴布局;
	//滚动窗口->mf_DrawFun	= f_draw时间轴;
	滚动窗口->mf_动画更新	= f_时间轴动画;
	滚动窗口->mf_鼠标滚轮 = nullptr;
	//滚动窗口->mf_鼠标按键按下	= f_时间轴页面鼠标按下;
	//滚动窗口->mf_鼠标按键放开	= f_时间轴页面鼠标放开;
	//滚动窗口->mf_鼠标移动		= f_时间轴页面鼠标位置改变;
	S_鼠标键位映射* 鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位 = f_widget_init_鼠标键位映射();
	鼠标键位->event = f_工作区_横向缩放页面视口;
	鼠标键位->鼠标按键[0] = E_Input_鼠标按键::e_滚轮;
	鼠标键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	鼠标键位->发生组件 = 时间轴;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)鼠标键位);


	S_拖拽键位映射* 拖拽键位 = f_widget_init_拖拽键位映射();
	拖拽键位->event = f_时间轴页面工作区_拖拽时间帧;
	拖拽键位->鼠标按键[0] = E_Input_鼠标按键::e_左键;
	拖拽键位->鼠标状态[0] = DEF_按键状态_按下 | DEF_按键状态_按下中;
	拖拽键位->发生组件 = 时间轴;
	f_ui_注册鼠标快捷键(滚动窗口, (S_键位映射*)拖拽键位);


	return 滚动窗口;
}






E_事件是否传递 f_时间轴页面工作区_拖拽时间帧(C_Widget* self, uint8 状态) {
	C_时间轴* view = (C_时间轴*)self;
	
	auto c = f_widget_get鼠标局部位置(self->g_鼠标.gPos, self);
	int64 当前帧 = ((c.x - self->m_扩展视口属性->m_中心.x)) / self->m_扩展视口属性->m_比例.x / S_时间轴帧绘制信息::g时间区间缩放;

	f_NodeCtx_set场景当前时间(当前帧);
	std::cout<<"f_prop_I32(f_NodeCtx_get帧().当前帧)"<< f_prop_I32(f_NodeCtx_get帧().当前帧)<<std::endl;

	for (auto& e : C_时间轴::g_当前时间轴页面) {
		if (!e->m_被裁剪) {
			e->f_刷新时间帧绘制();
		}
	}

	f_时间工作区_刷新时间线绘制(view, view->m_时间线绘制, f_prop_I32(f_NodeCtx_get帧().当前帧), self->m_父部件->m_Size.y);
	//f_时间工作区_时间线绘制(view, view->m_时间线绘制);
	f_页面_更新联动工作区(E_工作区类型::e_时间轴);

	f_node_帧更新(true);
	return E_事件是否传递::e_事件传递_终止;
}








